package com.qzxy.premiumhotelsystem.controller.admin;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.qzxy.premiumhotelsystem.common.annotation.LogExecutionTime;
import com.qzxy.premiumhotelsystem.common.constant.CaptchaConstant;
import com.qzxy.premiumhotelsystem.common.constant.UserRoleConstant;
import com.qzxy.premiumhotelsystem.common.enums.LogLevel;
import com.qzxy.premiumhotelsystem.domain.entity.Admin;
import com.qzxy.premiumhotelsystem.common.result.Result;
import com.qzxy.premiumhotelsystem.domain.entity.Employees;
import com.qzxy.premiumhotelsystem.service.AdminService;
import com.qzxy.premiumhotelsystem.service.EmployeesService;
import com.qzxy.premiumhotelsystem.service.LogsService;
import com.qzxy.premiumhotelsystem.utils.Bcrypt;
import com.qzxy.premiumhotelsystem.utils.IpUtil;
import com.qzxy.premiumhotelsystem.utils.KeysUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import static com.qzxy.premiumhotelsystem.common.result.ResultCodeEnum.*;

/**
 * ClassName: AdminController
 * Package: com.qzxy.premiumhotelsystem.controller
 * Description:
 *
 * @Author Qwh
 * @Create 2024/9/12 16:01
 * @Version 1.0
 */

//@SaCheckRole(type = UserRoleConstant.ADMIN)
@RestController
@Tag(name = "管理员接口")
@RequestMapping("/admin")
public class AdminController {
    @Resource
    private AdminService adminService;
    @Resource
    private EmployeesService employeesService;
    @Resource
    private Bcrypt bcrypt;

    /**
     * 管理员登录
     *
     * @param admin
     * @param Vcode
     * @return
     */
    @Operation(summary = "管理员登录")
    @PostMapping("/verification/{Vcode}")
    @LogExecutionTime(message = "管理员登录")
    @Transactional
//    @SaIgnore
    public Result Login(@RequestBody @Valid Admin admin, @PathVariable(value = "Vcode") @NotBlank String Vcode, HttpServletRequest request) {

        String clientIp = IpUtil.getClientIp(request);
        String key = CaptchaConstant.LOGIN_V_CODE.concat("_" + clientIp);

        if (!KeysUtil.validateCaptcha(key, Vcode)) {
            return Result.build("验证码错误 请重新输入", CAPTCHA_INVALID);
        }

        String login = adminService.login(admin);
        if (!login.isBlank()) {
            if (bcrypt.matches(admin.getPassword(), login)) {
                //切换为guest用户，进行登录
//                StpUtil.setStpLogic(adminStpLogic);
                StpUtil.login(admin.getUsername(), new SaLoginModel()
                        .setExtra("role", UserRoleConstant.ADMIN));

//                logsMapper.create(admin.getUsername(), "登录");

                return Result.ok(StpUtil.getTokenInfo().tokenValue);
            } else {
                return Result.build("密码错误", PASSWORD_ERROR);
            }
        } else {
            return Result.build("用户不存在", USERNAME_ERROR);
        }
    }

    /**
     * 获取个人信息
     * @return
     */
    @Operation(summary = "个人信息")
//    @SaIgnore
    @PostMapping("/me")
    public Result Me() {
        Admin admin = adminService.getByUsername(StpUtil.getLoginId().toString());
        if (admin!=null) {
            return Result.ok(admin);
        } else {
            return Result.error("请先登录");
        }
    }

    /**
     * 退出登录
     *
     * @return
     */
    @SaCheckLogin
    @Operation(summary = "退出登录")
    @Transactional
    @PostMapping("/logout")
    @LogExecutionTime(message = "退出登录")
    public Result logout() {
//        logsService.create("退出登录");
        StpUtil.logout();
        return Result.ok("退出登录成功");
    }


    /**
     * 查看登录会话是否登录
     *
     * @return
     */
    @Operation(summary = "管理员登录会话", description = "查看登录会话是否登录")
    @GetMapping("/is-login")
    public Result isLogin() {
        // 查看当前会话是否登录
        boolean isLogin = StpUtil.isLogin();
        String token = isLogin ? (String) StpUtil.getTokenInfo().tokenValue : null;
        return Result.build(token, isLogin ? 200 : 403, isLogin ? "管理员已经登录" : "管理员未登录无权操作");
    }

    /**
     * 检查是否登录
     *
     * @return
     */
    @Operation(summary = "管理员是否登录", description = "管理员是否登录")
    @GetMapping("/check-login")
    public Result checkLogin() {
        // 未登录将直接报错
        StpUtil.checkLogin();
        return Result.ok("管理员已经登录");
    }


}
